package org.mte.sak.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

/**
 * Gestisce i formati numerici.
 *
 * @author Marco Traversari
 * @version $Revision: 1.4 $ $Date: 2012-05-28 10:39:34 $
 */
public class NumberHandler {

	/**
	 * Formatta un <code>double</code> secondo il <code>Locale</code>
	 * specificato.
	 *
	 * @param number
	 * @param decimalDigitsNumber sono le eventuali cifre decimali da considerare
	 * @param locale
     * @throws ParseException
	 * @return la stringa con il numero formattato
	 */
	public static String format(double number, int decimalDigitsNumber, Locale locale) throws ParseException {
		return format(number, "#,##0", decimalDigitsNumber, locale) ;
	}
	
	/**
	 * Formatta un <code>double</code> secondo il <code>Locale</code>
	 * specificato.
	 *
	 * @param number
	 * @param pattern
	 * @param decimalDigitsNumber sono le eventuali cifre decimali da considerare
	 * @param locale
     * @throws ParseException
	 * @return la stringa con il numero formattato
	 */
	public static String format(double number, String pattern, int decimalDigitsNumber, Locale locale) throws ParseException {
		String strNumber = "";
		NumberFormat numberFormat = NumberFormat.getInstance(locale);
		if (decimalDigitsNumber > 0) {
			pattern += ".";
		}
		for (int i = 0; i < decimalDigitsNumber; i++) {
			pattern += "0";
		}
		if (numberFormat instanceof DecimalFormat) {
			((DecimalFormat) numberFormat).applyPattern(pattern);
		}
		strNumber = numberFormat.format(number);
		return strNumber;
	}

    /**
     * Formatta un <code>BigDecimal</code> secondo il <code>Locale</code>
     * specificato.
     *
     * @param number
     * @param decimalDigitsNumber
     * @param locale
     * @throws ParseException
     * @return una stringa rappresentante il numero.
     */
    public static String format(BigDecimal number, int decimalDigitsNumber, Locale locale) throws ParseException {
        return format(number.doubleValue(), decimalDigitsNumber, locale);
    }

	/**
	 * Converte il valore di una stringa in un <code>double</code>.
	 *
	 * @param strNumber
	 * @param locale
	 * @return il numero come <code>double</code>
	 * @throws ParseException se la stringa non è rappresentabile come
	 * <code>double</code>.
	 */
	public static double parse(String strNumber, Locale locale) throws ParseException {
		double number = 0;
		if (strNumber != null) {
			NumberFormat numberFormat = NumberFormat.getInstance(locale);
			number = (numberFormat.parse(strNumber)).doubleValue();
		}
		return number;
	}

	/**
	 * Converte il valore di una stringa in un <code>BigDecimal</code>.
	 *
	 * @param strNumber
	 * @param locale
	 * @return il numero come <code>BigDecimal</code>
	 * @throws ParseException se la stringa non è rappresentabile come
	 * <code>double</code>.
	 */
	public static BigDecimal parseBigDecimal(String strNumber, Locale locale) throws ParseException {
		Double d = parse(strNumber, locale);
		strNumber = d.toString();
		BigDecimal number = new BigDecimal(strNumber);
		return number;
	}

	/**
	 * random
	 * @return random number
	 */
	public static Double random(int scale, int decimalDigitsNumber) throws ParseException {
		double n = Math.random() * scale;
		Locale locale = Locale.ENGLISH;
		String strNumber = format(n, decimalDigitsNumber, locale);
		n = parse(strNumber, locale);
		return n;
	}
	
	/**
	 * roundFloat
	 * @param number
	 * @param decimalDigits
	 * @return float
	 */
	public static Float roundFloat(float number, int decimalDigits) {
		return new Float(roundDouble(number, decimalDigits));
	}
	
	/**
	 * roundDouble
	 * @param number
	 * @param decimalDigits
	 * @return double
	 */
	public static Double roundDouble(double number, int decimalDigits) {
		Double roundedNumber = number;
		try {
			roundedNumber = new Double(format(number, "###0", decimalDigits, Locale.ENGLISH));
		} catch (ParseException pe) {
			System.out.println("pe=" + pe);
		}
		return roundedNumber;
	}
}